#ifndef __KEYPAD_ENGINE_H__
#define __KEYPAD_ENGINE_H__

#include <stdint.h>

#define KEYPAD_USE_LONG_HOLD         (1)

typedef enum
{
    KEYPAD_STAGE_DEFAULT  = 0,  /* 按键判断的默认状态 */
    KEYPAD_STAGE_DEBOUNCE = 1,  /* 按键判断的第一阶段，消抖 */
    KEYPAD_STAGE_SHORT    = 2,  /* 按键判断的第二阶段，短按判断 */
    KEYPAD_STAGE_LONG     = 3   /* 按键判断的第三阶段，长按判断 */
}keypad_stage_e;

typedef enum
{
    KEYPAD_EVENT_NONE  = 0,        /* 没有按键按下 */
    KEYPAD_EVENT_SHORT_PRESS = 1,  /* 按键短按（单击） */
    KEYPAD_EVENT_MULTI_CLICK = 2,  /* 按键双击 */
    KEYPAD_EVENT_LONG_PRESS  = 3,  /* 按键长按 */
    KEYPAD_EVENT_LONG_HOLD   = 4,  /* 按键长按，一直不放 */
    KEYPAD_EVENT_LONG_UP     = 5   /* 长按抬起 */
}keypad_event_e;

/* 事件响应回调函数类型 */
typedef void (*keypad_response_callback) (void *);

typedef struct keypad
{
    struct keypad *next;

    uint8_t (*key_pin_read) (void *);  /* 获取按键IO电平状态 */
    keypad_response_callback callback;  /* 按键响应回调函数 */

    keypad_stage_e stage;
    keypad_event_e event;
    
    uint8_t id;
    uint8_t  short_press_flag;  /* 按键短按（单击）标志 */
    uint16_t scan_count;        /* 扫描计数器 */
    uint16_t debounce_time;     /* 消抖时间 */ 
    uint16_t long_press_time;   /* 按键长按 */

    uint16_t multi_click_down_count;  /* 点击超时计数器 */
    uint16_t multi_click_down_timeout;  /* 双击超时时间（超出这个时间没有再次按下则认为是单击） */
    uint16_t multi_clicks;  /* 多次点击次数 */

#if KEYPAD_USE_LONG_HOLD
    uint16_t long_hold_out_count;
    uint16_t long_hold_out_time;    /* 按键保持输出 */
#endif  /* end oif #if KEYPAD_USE_LONG_HOLD */
}keypad_t;

int32_t keypad_register(keypad_t *key);
keypad_event_e keypad_event_read(keypad_t *key);
uint8_t keypad_scan(void);

#endif  /* __KEYPAD_ENGINE_H__ */
